package dao;

import anno.Component;
import pojo.Hall;
import pojo.Movie;
import pojo.Showtime;
import utils.JDBCUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ShowtimeDAO extends AbstractBaseDao<Showtime> {

    /**
     * 分页模糊查询场次，并关联电影和影厅信息
     *
     * @param keyword  模糊查询关键字
     * @param pageNum  当前页码
     * @param pageSize 每页记录数
     * @return 分页查询结果
     * @throws SQLException SQL异常
     */
    public Map<String, Object> findShowtimesByPageAndMovieId(String keyword, int pageNum, int pageSize) throws SQLException {
        String sql = "SELECT s.*, m.title AS movie_title, m.description AS movie_description, m.release_date AS movie_release_date, " +
                "m.duration AS movie_duration, m.rating AS movie_rating, m.poster AS movie_poster, m.created_at AS movie_created_at, " +
                "h.cinema_id AS hall_cinema_id, h.name AS hall_name, h.seats_layout AS hall_seats_layout, h.created_at AS hall_created_at " +
                "FROM tb_showtimes s " +
                "JOIN tb_movies m ON s.movie_id = m.id " +
                "JOIN tb_halls h ON s.hall_id = h.id " +
                "WHERE m.title LIKE ?";
        return findByPageAndKeyword(sql, keyword, pageNum, pageSize);
    }

    /**
     * 根据电影ID查询场次
     *
     * @param movieId 电影ID
     * @return 符合条件的场次列表
     * @throws SQLException SQL异常
     */
    public List<Showtime> findByMovieId(Integer movieId) throws SQLException {
        return findByField("movieId", movieId);
    }

    /**
     * 根据影厅ID查询场次
     *
     * @param hallId 影厅ID
     * @return 符合条件的场次列表
     * @throws SQLException SQL异常
     */
    public List<Showtime> findByHallId(Integer hallId) throws SQLException {
        return findByField("hallId", hallId);
    }

    /**
     * 根据放映开始时间查询场次
     *
     * @param startTime 放映开始时间
     * @return 符合条件的场次列表
     * @throws SQLException SQL异常
     */
    public List<Showtime> findByStartTime(LocalDateTime startTime) throws SQLException {
        return findByField("startTime", startTime);
    }

    /**
     * 分页模糊查询场次的辅助方法
     *
     * @param sql      查询SQL
     * @param keyword  模糊查询关键字
     * @param pageNum  当前页码
     * @param pageSize 每页记录数
     * @return 分页查询结果
     * @throws SQLException SQL异常
     */
    private Map<String, Object> findByPageAndKeyword(String sql, String keyword, int pageNum, int pageSize) throws SQLException {
        int offset = (pageNum - 1) * pageSize;
        String countSql = "SELECT COUNT(*) FROM (" + sql + ") tmp";
        String querySql = sql + " LIMIT ?, ?";

        // 查询符合条件的场次总数
        ResultSet rsCount = (ResultSet) JDBCUtils.execute(countSql, "%" + keyword + "%");
        int totalRecords = 0;
        if (rsCount.next()) {
            totalRecords = rsCount.getInt(1);
        }

        // 查询符合条件的场次列表
        ResultSet rsQuery = (ResultSet) JDBCUtils.execute(querySql, "%" + keyword + "%", offset, pageSize);
        List<Showtime> showtimeList = new ArrayList<>();
        while (rsQuery.next()) {
            showtimeList.add(mapResultSetToEntity(rsQuery));
        }

        // 将数据和总记录数封装到Map中
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("data", showtimeList);
        resultMap.put("total", totalRecords);

        return resultMap;
    }

    /**
     * 将ResultSet映射为Showtime实体
     *
     * @param rs ResultSet
     * @return Showtime实体
     * @throws SQLException SQL异常
     */
    @Override
    protected Showtime mapResultSetToEntity(ResultSet rs) throws SQLException {
        Showtime showtime = super.mapResultSetToEntity(rs);

        // 关联电影信息
        Movie movie = new Movie();
        movie.setId(rs.getInt("movie_id"));
        movie.setTitle(rs.getString("movie_title"));
        movie.setDescription(rs.getString("movie_description"));
        movie.setReleaseDate(rs.getTimestamp("movie_release_date").toLocalDateTime());
        movie.setDuration(rs.getInt("movie_duration"));
        movie.setRating(rs.getFloat("movie_rating"));
        movie.setPoster(rs.getString("movie_poster"));
        movie.setCreatedAt(rs.getTimestamp("movie_created_at").toLocalDateTime());
        showtime.setMovie(movie);

        // 关联影厅信息
        Hall hall = new Hall();
        hall.setId(rs.getInt("hall_id"));
        hall.setCinemaId(rs.getInt("hall_cinema_id"));
        hall.setName(rs.getString("hall_name"));
        hall.setSeatsLayout(rs.getString("hall_seats_layout"));
        hall.setCreatedAt(rs.getTimestamp("hall_created_at").toLocalDateTime());
        showtime.setHall(hall);

        return showtime;
    }
}